<?php
/*
 * @Author: 孙开源 && sunkaiyuan@namenode.cn
 * @Date: 2023-04-12 16:45:39
 * @LastEditors: 孙开源 && sunkaiyuan@namenode.cn
 * @LastEditTime: 2023-04-24 15:20:01
 * @Description: 
 * 
 */
namespace zhijingfeisuo\Kernel\Services;

use zhijingfeisuo\Kernel\Exceptions\InvalidCredentialsException;
use zhijingfeisuo\Kernel\Client;
use function zhijingfeisuo\tap;
use zhijingfeisuo\Kernel\Traits\ResponseCastable;

class AccessToken
    {
    use ResponseCastable;

    /**
     * @var \zhijingfeisuo\Application
     */
    protected $app;

    /**
     * AccessToken constructor.
     *
     * @param \zhijingfeisuo\Application
     */
    public function __construct($app)
        {
        $this->app = $app;
        }

    /**
     * 获取 AccessToken缓存
     *
     * @return string
     *
     * @throws \Psr\SimpleCache\InvalidArgumentException
     */
    public function getToken()
        {
        if ($value = $this->app->cacher->get("accessToken")) {
            return $value;
            }
        else
            return $this->refresh();
        }

    /**
     * @description: 账号换granteCode
     * @param string $clientId
     * @param string $loginAccount
     * @return array
     */
    public function getGrantCode($clientId, $loginAccount)
        {
        return (new Client($this->app))->popMiddleware('access_token')->postJson("uac/iuauthen/passwordSignOnGrant", ['clientId' => $clientId, 'loginAccount' => $loginAccount]);
        }
    /**
     * @description: granteCode换accessToken
     * @param string $clientId
     * @param string $grantCode
     * @param string $password
     * @return array
     */
    public function getAccessToken($clientId, $grantCode, $password)
        {
        return (new Client($this->app))->popMiddleware('access_token')->postJson("uac/authen/getAccessTokenByPassword", ['clientId' => $clientId, 'grantCode' => $grantCode, 'password' => $password]);
        }
    /**
     * @description: 刷新 过期 AccessToken
     * @return array
     */
    public function refreshToken()
        {
        $response = (new Client($this->app))->popMiddleware('access_token')->postJson("uac/authen/refreshAccessToken", [
            'clientId'     => $this->app->config->get('clientId'),
            'endUserId'    => $this->app->cacher->get("userId"),
            'refreshToken' => $this->app->cacher->get("refreshToken")
        ]);
        return $this->saveCache($response);
        }
    /**
     * @description: 刷新 失效 AccessToken
     * @return array
     */
    public function refresh()
        {
        $response = $this->getGrantCode($this->app->config->get('clientId'), $this->app->config->get('loginAccount'));
        $response = $this->getAccessToken($this->app->config->get('clientId'), $response['result']['grantCode'], $this->app->config->get('password'));
        return $this->saveCache($response);
        }

    /**
     * @description: 保存token 到缓存
     * @param array $response
     * @return array
     */
    public function saveCache($response)
        {

        $response = $response['result'];
        if (isset($response['successful']) && true == $response['successful']) {
            throw new InvalidCredentialsException(json_encode($response));
            }
        $this->app->cacher->set("accessToken", $response['accessToken'], $response['accessTokenExpire']);
        $this->app->cacher->set("ciamToken", $response['ciamToken'], $response['ciamTokenExpire']);
        $this->app->cacher->set("refreshToken", $response['refreshToken'], $response['refreshTokenExpire']);
        $this->app->cacher->set("userId", $response['userId']);
        return $response;

        }

    }